package com.k2data.k2app.controller;

import com.k2data.k2app.constant.Constant;
import com.k2data.k2app.domain.EventCond;
import com.k2data.k2app.domain.po.EventMaintenance;
import com.k2data.k2app.domain.po.v1.Event;
import com.k2data.k2app.domain.po.v1.EventFaultV1;
import com.k2data.k2app.mapper.EventDeviceMapper;
import com.k2data.k2app.mapper.EventMaintenanceMapper;
import com.k2data.k2app.mapper.EventMapper;
import com.k2data.k2app.response.CommonResultResponse;
import com.k2data.k2app.response.PageInfo;
import com.k2data.k2app.response.ResponseHelper;
import com.k2data.k2app.rest.SysClient;
import com.k2data.k2app.rest.domain.RectList;
import com.k2data.k2app.service.EventService;
import com.k2data.k2app.service.EventV1Service;
import com.k2data.k2app.service.KmxService;
import com.k2data.k2app.utils.StringUtils;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author lidong9144@163.com 17-3-17.
 */
@RestController
@RequestMapping("/events1")
public class Event1Controller {
    @Autowired
    private SysClient sysClient;
    @Autowired
    private EventMapper eventMapper;

    private final EventService eventService;

    private final EventMaintenanceMapper eventMaintenanceMapper;
    private final KmxService kmxService;
    private final EventDeviceMapper eventDeviceMapper;
    private final EventV1Service eventV1Service;

    @Autowired
    public Event1Controller (EventService eventService, EventV1Service eventV1Service,
                             EventMaintenanceMapper eventMaintenanceMapper,
                             KmxService kmxService,
                             EventDeviceMapper eventDeviceMapper) {
        this.eventService = eventService;
        this.eventV1Service = eventV1Service;

        this.eventMaintenanceMapper = eventMaintenanceMapper;
        this.kmxService = kmxService;
        this.eventDeviceMapper = eventDeviceMapper;
    }

    @ApiOperation(value = "添加故障事件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "event", value = "event", required = true, dataType = "Event", paramType = "body")
    })
    @PostMapping(value = "/faults", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> postFaultEvent(@RequestBody Event event) throws Exception {
        event.setType("fault");
        return ResponseHelper.success(eventV1Service.insertEvent(event));
    }
    @ApiOperation(value = "添加事件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "event", value = "event", required = true, dataType = "Event", paramType = "body")
    })
    @PostMapping(value = "/maintenance", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> postMaintenanceEvent(@RequestBody Event event) throws Exception {
        return ResponseHelper.success(eventV1Service.insertEvent(event));
    }

    @ApiOperation(value = "更新事件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "eventId", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "event", value = "event", required = true, dataType = "Event", paramType = "body")
    })
    @PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> putEvent(@PathVariable("id") Long id,
                                                         @RequestBody Event event) throws Exception {
        event.setId(id);

        return ResponseHelper.success(eventV1Service.updateEvent(event));
    }

    @ApiOperation(value = "删除事件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path")
    })
    @DeleteMapping(value = "/{id}")
    public ResponseEntity<CommonResultResponse> deleteEvent(@PathVariable("id") Long id) throws Exception {
        return ResponseHelper.success(eventDeviceMapper.deleteByPrimaryKey(id));
    }

    @ApiOperation(value = "获取设备对应的文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "deviceId", required = true, dataType = "Long", paramType = "path")
    })
    @GetMapping(value = "/{id}/files")
    public ResponseEntity<CommonResultResponse> getFiles(@PathVariable("id") Long id) throws Exception {
        return ResponseHelper.success(eventV1Service.getFileUrls(id));
    }

    @ApiOperation(value = "更新维修事件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "eventId", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "event", value = "event", required = true, dataType = "EventMaintenance", paramType = "body")
    })
    @PutMapping(value = "/maintenances/{id}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> putEventMaintenance(@PathVariable("id") Long id,
                                                              @RequestBody EventMaintenance event) throws Exception {
        event.setId(id);

        return ResponseHelper.success(eventService.updateEventMaintenance(event));
    }

    @ApiOperation(value = "删除维修事件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "eventId", required = true, dataType = "Long", paramType = "path")
    })
    @DeleteMapping(value = "/maintenances/{id}")
    public ResponseEntity<CommonResultResponse> deleteEventMaintenance(@PathVariable("id") Long id) throws Exception {
        return ResponseHelper.success(eventMaintenanceMapper.deleteByPrimaryKey(id));
    }

    @ApiOperation(value = "故障数量统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "userId", required = false, dataType = "Long", paramType = "query")
    })
    @GetMapping(value = "/faults/count")
    public ResponseEntity<CommonResultResponse> getCount( @RequestParam(value = "userId", required = false) Long userId) throws Exception {
        Event dto = new Event();
        dto.setType("fault");

        // 判断用户是否是系统管理员
        if(userId !=null){
            RectList rolesByUser = sysClient.getRolesByUser(userId);
            List list = rolesByUser.getResult();
            if(list!=null && list.size()>0){
                for(int i=0;i<list.size();i++){
                    Map map = (Map)list.get(i);
                    if(map.get("enname")!=null && !"Administrator".equals(map.get("enname").toString())){
                        dto.setUserId(userId);
                    }
                }
            }
        }

        List<Event> events = eventMapper.selectTypeCount(dto);
        Integer count = 0 ;
        for(Event event:events){
            count += event.getCount();
        }
        dto.setCount(count);
        dto.setTypeCount(events.size());
        dto.setStartTime(kmxService.getKmxStartTime());
        dto.setEndTime(LocalDateTime.now());

        return ResponseHelper.success(dto);
    }

    @ApiOperation(value = "故障类型")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "userId", required = false, dataType = "Long", paramType = "query")
    })
    @GetMapping(value = "/faults/types")
    public ResponseEntity<CommonResultResponse> getFaultType( @RequestParam(value = "userId", required = false) Long userId) throws Exception {
        Event event = new Event();
        event.setType("fault");

        // 判断用户是否是系统管理员
        if(userId !=null){
            RectList rolesByUser = sysClient.getRolesByUser(userId);
            List list = rolesByUser.getResult();
            if(list!=null && list.size()>0){
                for(int i=0;i<list.size();i++){
                    Map map = (Map)list.get(i);
                    if(map.get("enname")!=null && !"Administrator".equals(map.get("enname").toString())){
                        event.setUserId(userId);
                    }
                }
            }
        }
        List<Event> events = eventMapper.selectTypeCount(event);
        List<String> types = events.stream().map(Event::getEventType).collect(Collectors.toList());
        return ResponseHelper.success(types);
    }

    @ApiOperation(value = "故障事件类型数量")
    @GetMapping(value = "/faults/types/count")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId", value = "deviceId", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "type", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "customer_id", value = "客户id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "userId", value = "userId", required = false, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "date", paramType = "query"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "date", paramType = "query")
    })
    public ResponseEntity<CommonResultResponse> getFaultBarChart(
            @RequestParam(value = "deviceId", required = false) Long deviceId,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "userId", required = false) Long userId,
            @RequestParam(value = "customer_id", required = false) Long customerId,
            @RequestParam(value = "startDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startDate,
            @RequestParam(value = "endDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endDate
    ) throws Exception {
        Event cond = new Event();
        cond.setDeviceId(deviceId);
        cond.setCustomerId(customerId);
        cond.setStartTimeGreater(startDate);
        cond.setEndTimeGreater(endDate);
        cond.setType(type);
        // 判断用户是否是系统管理员
        if(userId !=null){
            RectList rolesByUser = sysClient.getRolesByUser(userId);
            List list = rolesByUser.getResult();
            if(list!=null && list.size()>0){
                for(int i=0;i<list.size();i++){
                    Map map = (Map)list.get(i);
                    if(map.get("enname")!=null && !"Administrator".equals(map.get("enname").toString())){
                        cond.setUserId(userId);
                    }
                }
            }
        }

        return ResponseHelper.success(eventV1Service.faultBarChart(cond));
    }

    @ApiOperation(value = "故障事件类型数量")
    @GetMapping(value = "/faults/type/count")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId", value = "deviceId", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "type", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "customer_id", value = "客户id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "userId", value = "userId", required = false, dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "date", paramType = "query"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "date", paramType = "query")
    })
    public ResponseEntity<CommonResultResponse> getFaultCount(
            @RequestParam(value = "deviceId", required = false) Long deviceId,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "userId", required = false) Long userId,
            @RequestParam(value = "customer_id", required = false) Long customerId,
            @RequestParam(value = "startDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startDate,
            @RequestParam(value = "endDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endDate
    ) throws Exception {
        Event cond = new Event();
        cond.setDeviceId(deviceId);
        cond.setCustomerId(customerId);
        cond.setStartTimeGreater(startDate);
        cond.setEndTimeGreater(endDate);
        cond.setType(type);
        // 判断用户是否是系统管理员
        if(userId !=null){
            RectList rolesByUser = sysClient.getRolesByUser(userId);
            List list = rolesByUser.getResult();
            if(list!=null && list.size()>0){
                for(int i=0;i<list.size();i++){
                    Map map = (Map)list.get(i);
                    if(map.get("enname")!=null && !"Administrator".equals(map.get("enname").toString())){
                        cond.setUserId(userId);
                    }
                }
            }
        }

        return ResponseHelper.success(eventV1Service.selectFaultCount(cond));
    }

    @ApiOperation(value = "事件列表")
    @GetMapping(value = "/events")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "date", paramType = "query"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "date", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "类型", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "customerId", value = "客户", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "userId", value = "当前登陆用户id(userId)", dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "deviceId", value = "设备", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "name", value = "事件名称", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "keyName", value = "关键字", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小(默认 30)", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "order", value = "(desc, asc)", dataType = "string", paramType = "query")
    })
    public ResponseEntity<CommonResultResponse> getFaultList(
            @RequestParam(value = "startDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDateTime startDate,
            @RequestParam(value = "endDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDateTime endDate,
            @RequestParam(value = "pageNum", required = false) Integer pageNum,
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "customerId", required = false) String customerId,
            @RequestParam(value = "userId", required = false) Long userId,
            @RequestParam(value = "deviceId", required = false) String deviceId,
            @RequestParam(value = "name", required = false) String name,
            @RequestParam(value = "keyName", required = false) String keyName,
            @RequestParam(value = "order", required = false) String order) throws Exception {
        EventFaultV1 cond = new EventFaultV1();
        cond.setStartTimeGreater(startDate);
        cond.setEndTimeGreater(endDate);
        cond.setType(type);
        cond.setEventName(name);
        if (!StringUtils.isEmpty(customerId)){
            cond.setCustomerId(Long.parseLong(customerId));
        }
        if (!StringUtils.isEmpty(deviceId)){
            cond.setDeviceId(Long.parseLong(deviceId));
        }
        if (!StringUtils.isEmpty(keyName)){
            cond.setKeyName(keyName);
        }
        if ("desc".equals(order)) {
            cond.setOrderBy("start_time DESC");
        }

        if(userId!=null && !"".equals(userId)){
            // 权限过滤，管理员不加权限过滤功能，默认所有权限
            RectList rolesByUser = sysClient.getRolesByUser(userId);
            List list = rolesByUser.getResult();
            if(list!=null && list.size()>0){
                Map map = (Map)list.get(0);
                if(map.get("enname")!=null && !"Administrator".equals(map.get("enname").toString())){
                    cond.setUserId(userId);
                }
            }else{
                //用户没有角色，所以也不是管理员，关联查询
                cond.setUserId(userId);
            }
        }

        List<Event> source = eventV1Service.getAllEventList(cond);


        int pageNumReal = pageNum == null ? 1 : pageNum;
        int pageSizeReal = pageSize == null ? Constant.DEFAULT_PAGE_SIZE : pageSize;
        PageInfo pageInfo = new PageInfo(pageNumReal, pageSizeReal, source.size());


        int fromIndex = (pageNumReal - 1) * pageSizeReal;
        if (fromIndex > source.size()) {
            fromIndex = source.size();
        }
        int toIndex = pageNumReal * pageSizeReal;
        if (toIndex > source.size()) {
            toIndex = source.size();
        }
        return ResponseHelper.success(source.subList(fromIndex,toIndex), pageInfo);
    }


    @ApiOperation(value = "维修事件类型数量")
    @GetMapping(value = "/maintenances/types/count")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId", value = "deviceId", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", dataType = "date", paramType = "query"),
            @ApiImplicitParam(name = "endDate", value = "结束时间", dataType = "date", paramType = "query")
    })
    public ResponseEntity<CommonResultResponse> getMaintenanceBarChart(
            @RequestParam(value = "deviceId", required = false) Long deviceId,
            @RequestParam(value = "startDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startDate,
            @RequestParam(value = "endDate", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endDate
    ) throws Exception {
        EventCond cond = new EventCond();
        cond.setDeviceId(deviceId);
        cond.setStartTimeGreater(startDate);
        cond.setStartTimeLess(endDate);

        return ResponseHelper.success(eventService.maintenanceBarChart(cond));
    }
}
